<template>
    <el-dialog v-model="dialogVisible" title="混搭设置" width="800px" :before-close="handleClose" destroy-on-close>

        <el-form :model="mixSettings" label-position="top">
            <el-form-item label="单个视频片段最高重复次数">
                <el-input-number v-model="mixSettings.max_freq" :min="1" :max="5" />
            </el-form-item>

            <el-form-item label="目标视频数量">
                <el-input-number v-model="mixSettings.target_videos" :min="1" :max="200" />
                <el-help class="form-help-text">
                    设置目标视频数量，会尽量生成接近这个数量的视频组合，生成后就不再生成新的组合。
                </el-help>
            </el-form-item>

            <el-form-item label="最少片段个数">
                <el-input-number v-model="mixSettings.min_clips_per_video" :min="2" :max="30" />
                <el-help class="form-help-text">
                    每个视频的最小片段数量, 平均一个就是5s。
                </el-help>
            </el-form-item>
        </el-form>

        <el-button type="primary" @click="genPreview" :loading="previewLoading">
            生成预览
        </el-button>

        <!-- 分析结果展示区域 -->
        <div v-if="previewData.length > 0" class="analysis-section">
            <el-divider content-position="center">分析结果</el-divider>

            <!-- 视频使用频率统计 -->
            <div class="frequency-analysis">
                <h3>视频使用频率分析</h3>
                <el-row>
                    <el-col :span="12">
                        <div class="stat-item">
                            <span class="stat-label">视频总数:</span>
                            <span class="stat-value">{{ videoStats.totalUniqueVideos }} 个</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-label">平均出现频率:</span>
                            <span class="stat-value">{{ videoStats.averageFrequency.toFixed(2) }} 次/视频</span>
                        </div>
                    </el-col>
                    <el-col :span="12">
                        <div class="stat-item">
                            <span class="stat-label">最高出现频率:</span>
                            <span class="stat-value">{{ videoStats.maxFrequency }} 次</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-label">最低出现频率:</span>
                            <span class="stat-value">{{ videoStats.minFrequency }} 次</span>
                        </div>
                    </el-col>
                </el-row>

                <!-- 频率分布图表 -->
                <el-progress :percentage="videoStats.frequencyDiversity * 100"
                    :format="() => `均匀度: ${(videoStats.frequencyDiversity * 100).toFixed(1)}%`"
                    :color="frequencyDiversityColor"
                    :status="videoStats.frequencyDiversity > 0.7 ? 'success' : 'warning'" class="diversity-progress" />
            </div>

        </div>

        <el-collapse class="preview-section" v-if="previewData.length > 0">
            <el-collapse-item title="预览组合详情" name="preview-list">
            <div class="video-list" style="max-height: 300px; overflow-y: auto;">
                <div v-for="(combo, idx) in previewData" :key="idx" class="video-item">
                <span class="video-index">#{{ idx + 1 }}</span>
                <div class="video-sequence">
                    <div v-for="(video, vIdx) in combo" :key="vIdx" class="video-sequence-item">
                    <span class="video-filename">{{ video }}</span>
                    </div>
                </div>
                </div>
            </div>
            </el-collapse-item>
        </el-collapse>

        <template #footer>
            <span class="dialog-footer">
                <el-button @click="handleClose">取消</el-button>
                <el-button type="primary" :loading="submitting"
                    :disabled="!hasSelectedVideos || previewData.length === 0" @click="submitMix">
                    开始混搭
                </el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script>
import { defineComponent, ref, computed, watch, reactive } from 'vue';
import mergeService from '../services/mergeService';
import { ElMessage } from 'element-plus';

export default defineComponent({
    name: 'SingleFolderMixDialog',

    props: {
        visible: {
            type: Boolean,
            default: false
        },
        selectedVideos: {
            type: Array,
            default: () => []
        }
    },

    emits: ['update:visible', 'submit'],

    setup(props, { emit }) {
        // Dialog state
        const dialogVisible = ref(false);
        const submitting = ref(false);
        const previewLoading = ref(false);

        // Data states
        const previewData = ref([]);
        const duplicatedSequences = ref([]);

        // Settings
        const mixSettings = reactive({
            outputName: '',
            repeat_max: 1,
            target_videos: 30,
            min_clips_per_video: 8,
            max_freq: 3

        });

        // Computed
        const hasSelectedVideos = computed(() => props.selectedVideos && props.selectedVideos.length > 0);

        // 统计视频使用频率
        const videoStats = computed(() => {
            if (!previewData.value.length) {
                return {
                    totalUniqueVideos: 0,
                    averageFrequency: 0,
                    maxFrequency: 0,
                    minFrequency: 0,
                    frequencyDiversity: 0
                };
            }

            // 重新统计频率
            const videoFrequency = {};
            previewData.value.forEach(combo => {
                combo.forEach(video => {
                    videoFrequency[video] = (videoFrequency[video] || 0) + 1;
                });
            });
            const frequencies = Object.values(videoFrequency);
            let maxFreq = 0, maxFreqTimes = 0, minFreq = 0, avgFreq = 0;

            if (frequencies.length > 0) {
                maxFreq = Math.max(...frequencies);
                maxFreqTimes = frequencies.filter(freq => freq === maxFreq).length;
                minFreq = Math.min(...frequencies);
                avgFreq = frequencies.reduce((sum, freq) => sum + freq, 0) / frequencies.length;
            }

            // 计算频率分布的均匀度 (1 - 标准差/平均值)，越接近1越均匀
            const variance = frequencies.reduce((sum, freq) => {
                return sum + Math.pow(freq - avgFreq, 2);
            }, 0) / frequencies.length;
            const stdDev = Math.sqrt(variance);
            const diversity = Math.max(0, Math.min(1, 1 - (stdDev / avgFreq)));

            return {
                totalUniqueVideos: previewData.value.length,
                averageFrequency: avgFreq,
                maxFrequency: maxFreq,
                maxFreqTimes: maxFreqTimes,
                minFrequency: minFreq,
                frequencyDiversity: diversity
            };
        });

        // 根据均匀度设置颜色
        const frequencyDiversityColor = computed(() => {
            const diversity = videoStats.value.frequencyDiversity;
            if (diversity > 0.8) return '#67C23A';  // 绿色  
            if (diversity > 0.6) return '#E6A23C';  // 黄色
            return '#F56C6C';  // 红色
        });

        // 获取文件名
        const getFilename = (path) => {
            if (!path) return 'Unknown';
            return path.split('\\').pop().split('/').pop();
        };

        // 格式化序列用于展示
        const formatSequence = (seq) => {
            if (!seq || !seq.length) return '';
            return seq.map(v => {
                const name = getFilename(v.path || v.id);
                return `${v.category || '未知'}/${name.substring(0, 15)}${name.length > 15 ? '...' : ''}`;
            }).join(' → ');
        };

        // 检测重复子序列
        const detectDuplicateSubsequences = (combinations) => {
            const subseqCounter = {};
            const duplicates = [];
            return duplicates

            combinations.forEach(combo => {
                const videos = combo;
                for (let i = 0; i <= videos.length - subLength; i++) {
                    // 创建子序列的唯一标识
                    const subseq = videos.slice(i, i + subLength).map(v => v.id || v.path).join(',');

                    if (!subseqCounter[subseq]) {
                        subseqCounter[subseq] = { count: 1, videos: videos.slice(i, i + subLength) };
                    } else {
                        subseqCounter[subseq].count += 1;

                        // 如果是第一次发现重复，加入列表
                        if (subseqCounter[subseq].count === 2) {
                            duplicates.push(subseqCounter[subseq]);
                        }
                    }
                }
            });

            return duplicates;
        };

        // 生成预览
        const genPreview = async () => {
            if (!hasSelectedVideos.value) {
                ElMessage.warning('请先选择要混搭的视频');
                return;
            }
            if (!mixSettings.target_videos || !mixSettings.min_clips_per_video || !mixSettings.max_freq){
                ElMessage.warning('请先设置混搭参数');
                return;
            }
            
            const category_order_count = {}
            props.selectedVideos.forEach(video => {
                category_order_count[video.category_order] = (category_order_count[video.category_order] || 0) + 1;
            });
            const category_count = Object.keys(category_order_count).length;

            if (mixSettings.min_clips_per_video > category_count) {
                ElMessage.warning('最少片段个数不能小于已选择的视频数量');
                return;
            }

            try {
                previewLoading.value = true;

                const video_ids = props.selectedVideos.map(video => ({
                    id: video.id,
                    category: video.category,
                    category_order: video.category_order,
                    path: video.path,
                }));

                const params = {
                    video_ids: video_ids,
                    repeat_max: mixSettings.repeat_max,
                    target_videos: mixSettings.target_videos,
                    min_clips_per_video: mixSettings.min_clips_per_video
                };

                const response = await mergeService.previewCombination(params);

                if (response && response.success) {
                    // 更新预览数据
                    const freqMap = {};
                    const new_preview_data = (response.data || []).map(combo => {
                        return combo.filter(video => {
                            freqMap[video] = (freqMap[video] || 0) + 1;
                            return freqMap[video] <= mixSettings.max_freq;
                        });
                    }).filter(combo => combo.length >= mixSettings.min_clips_per_video);
                    previewData.value = new_preview_data;

                    // 分析检测重复子序列
                    duplicatedSequences.value = detectDuplicateSubsequences(previewData.value);

                    ElMessage.success('组合预览生成成功');
                } else {
                    ElMessage.error(response?.message || '预览生成失败');
                }
            } catch (error) {
                console.error('生成预览失败:', error);
                ElMessage.error('生成预览失败: ' + (error.message || '未知错误'));
            } finally {
                previewLoading.value = false;
            }
        };

        // Watch for visibility changes from parent
        watch(() => props.visible, (newValue) => {
            dialogVisible.value = newValue;
        });

        // Watch for dialog visibility changes to update parent
        watch(dialogVisible, (newValue) => {
            emit('update:visible', newValue);
        });

        // Close dialog
        const handleClose = () => {
            dialogVisible.value = false;
        };

        // Submit mixing job
        const submitMix = () => {
            submitting.value = true;

            emit('submit', {
                settings: {
                    ...mixSettings,
                    combinations: previewData.value
                }
            });

            submitting.value = false;
            handleClose();
        };

        return {
            dialogVisible,
            mixSettings,
            previewData,
            previewLoading,
            hasSelectedVideos,
            submitting,
            videoStats,
            duplicatedSequences,
            frequencyDiversityColor,
            handleClose,
            genPreview,
            submitMix,
            getFilename,
            formatSequence
        };
    }
});
</script>

<style scoped>
.preview-section,
.analysis-section {
    margin-top: 20px;
    border-top: 1px solid #ebeef5;
    padding-top: 20px;
}

.form-help-text {
    margin-left: 10px;
    color: #909399;
    font-size: 12px;
}

.video-list {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.video-item {
    display: flex;
    gap: 5px;
    font-size: 14px;
    line-height: 1.5;
}

.video-index {
    font-weight: bold;
    min-width: 25px;
}

.video-category {
    color: #409EFF;
    min-width: 80px;
}

.video-filename {
    color: #606266;
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.frequency-analysis,
.duplicate-analysis {
    margin-bottom: 20px;
}

.stat-item {
    display: flex;
    margin-bottom: 8px;
}

.stat-label {
    width: 120px;
    color: #606266;
}

.stat-value {
    font-weight: bold;
}

.diversity-progress {
    margin-top: 15px;
}

.duplicates-list {
    margin-top: 10px;
}

.duplicate-item {
    margin-bottom: 8px;
    display: flex;
    align-items: center;
}

.sequence-index {
    min-width: 25px;
    font-weight: bold;
}

.sequence-content {
    flex: 1;
}

.sequence-count {
    margin-left: 10px;
    color: #F56C6C;
    font-weight: bold;
}
</style>